﻿/*    
    OpenMheg - A free MHEG-5 library
    Copyright (C) 2008 Dharmesh Malam

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Text;

namespace ASN1Decoder.Builders.Nodes
{
    class SequenceNode : ASN1Node , IEnumerable<ASN1Node>
    {
        internal List<ASN1Node> Arguments {get; private set;}
        
        internal SequenceNode()
            : base()
        {
            Arguments = new List<ASN1Node>();
        }

        internal int Size
        {
            get { return Arguments.Count; }
        }

        internal ASN1Node GetAt(int i)
        { 
            if (i < 0 || i >= Arguments.Count) Failure("Argument not found");
            return Arguments[i];
        }

        internal void InsertAt(ASN1Node b, int n)
        {
            Arguments.Insert(n, b);
        }

        internal void Append(ASN1Node b)
        {
            Arguments.Add(b);
        }

        internal void RemoveAt(int i)
        {
            Arguments.RemoveAt(i);
        }

        internal ASN1Node First
        {
            get
            {
                return Arguments[0];
            }
        }

        internal ASN1Node Second
        {
            get
            {
                return Arguments[1];
            }
        }

        internal ASN1Node Third
        {
            get
            {
                return Arguments[2];
            }
        }
        
        internal ASN1Node Fourth
        {
            get
            {
                return Arguments[3];
            }
        }

        internal ASN1Node Fifth
        {
            get
            {
                return Arguments[4];
            }
        }

        // Get an argument with a specific tag.  Returns NULL if it doesn't exist.
        // There is a defined order of tags for both the binary and textual representations.
        // Unfortunately they're not the same.
        internal TaggedNode GetNamedArg(ASN1ContextCodes tag)
        {
            return (TaggedNode) Arguments.Find((ASN1Node x) => x is TaggedNode && ((TaggedNode)x).Tag == tag);
            
        }

        internal TaggedNode this[ASN1ContextCodes tag]
        {
            get
            {
                return GetNamedArg(tag);
            }
        }

        internal TaggedNode this[ASN1UniversalCodes tag]
        {
            get
            {
                return GetNamedArg((ASN1ContextCodes)tag);
            }
        }

        #region IEnumerable<ASN1Node> Members

        public IEnumerator<ASN1Node> GetEnumerator()
        {
            return Arguments.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return Arguments.GetEnumerator();
        }

        #endregion

        public override string ToString()
        {
            return Arguments.Count+ " Items "+ base.ToString(); ;
        }
    }
}
